Implement full support for non-pointer pointers in custom allocators for vector. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@185093 91177308-0d34-0410-b5e6-96231b3b80d8 
diff --git a/include/__bit_reference b/include/__bit_reference index 1621deb..8ff3bf6 100644 --- a/include/__bit_reference +++ b/include/__bit_reference 
@@ -333,7 +333,7 @@  }  // do middle whole words  __storage_type __nw = __n / __bits_per_word; - _VSTD::memset(__first.__seg_, 0, __nw * sizeof(__storage_type)); + _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), 0, __nw * sizeof(__storage_type));  __n -= __nw * __bits_per_word;  // do last partial word  if (__n > 0) @@ -363,7 +363,7 @@  }  // do middle whole words  __storage_type __nw = __n / __bits_per_word; - _VSTD::memset(__first.__seg_, -1, __nw * sizeof(__storage_type)); + _VSTD::memset(_VSTD::__to_raw_pointer(__first.__seg_), -1, __nw * sizeof(__storage_type));  __n -= __nw * __bits_per_word;  // do last partial word  if (__n > 0) @@ -430,7 +430,9 @@  // __first.__ctz_ == 0;  // do middle words  __storage_type __nw = __n / __bits_per_word; - _VSTD::memmove(__result.__seg_, __first.__seg_, __nw * sizeof(__storage_type)); + _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_), + _VSTD::__to_raw_pointer(__first.__seg_), + __nw * sizeof(__storage_type));  __n -= __nw * __bits_per_word;  __result.__seg_ += __nw;  // do last word @@ -569,7 +571,9 @@  __storage_type __nw = __n / __bits_per_word;  __result.__seg_ -= __nw;  __last.__seg_ -= __nw; - _VSTD::memmove(__result.__seg_, __last.__seg_, __nw * sizeof(__storage_type)); + _VSTD::memmove(_VSTD::__to_raw_pointer(__result.__seg_), + _VSTD::__to_raw_pointer(__last.__seg_), + __nw * sizeof(__storage_type));  __n -= __nw * __bits_per_word;  // do last word  if (__n > 0) @@ -870,6 +874,7 @@  {  typedef typename _Cp::difference_type difference_type;  typedef typename _Cp::__storage_type __storage_type; + typedef typename _Cp::__storage_pointer __storage_pointer;  typedef typename _Cp::iterator iterator;  static const unsigned __bits_per_word = _Cp::__bits_per_word;  static const unsigned _Np = 4; @@ -880,9 +885,15 @@  _LIBCPP_INLINE_VISIBILITY static difference_type capacity()  {return static_cast<difference_type>(_Np * __bits_per_word);}  _LIBCPP_INLINE_VISIBILITY explicit __bit_array(difference_type __s) : __size_(__s) {} - _LIBCPP_INLINE_VISIBILITY iterator begin() {return iterator(__word_, 0);} - _LIBCPP_INLINE_VISIBILITY iterator end() {return iterator(__word_ + __size_ / __bits_per_word, - static_cast<unsigned>(__size_ % __bits_per_word));} + _LIBCPP_INLINE_VISIBILITY iterator begin() + { + return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0); + } + _LIBCPP_INLINE_VISIBILITY iterator end() + { + return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word, + static_cast<unsigned>(__size_ % __bits_per_word)); + }  };    template <class _Cp> 
diff --git a/include/iterator b/include/iterator index 3b078a2..dda053d 100644 --- a/include/iterator +++ b/include/iterator 
@@ -1135,7 +1135,14 @@  #endif  return *__i;  } - _LIBCPP_INLINE_VISIBILITY pointer operator->() const _NOEXCEPT {return &(operator*());} + _LIBCPP_INLINE_VISIBILITY pointer operator->() const _NOEXCEPT + { +#if _LIBCPP_DEBUG_LEVEL >= 2 + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable iterator"); +#endif + return (pointer)&reinterpret_cast<const volatile char&>(*__i); + }  _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator++() _NOEXCEPT  {  #if _LIBCPP_DEBUG_LEVEL >= 2 
diff --git a/include/vector b/include/vector index e04c267..046d92d 100644 --- a/include/vector +++ b/include/vector 
@@ -365,12 +365,7 @@  {return static_cast<size_type>(__end_cap() - __begin_);}    _LIBCPP_INLINE_VISIBILITY - void __destruct_at_end(const_pointer __new_last) _NOEXCEPT - {__destruct_at_end(__new_last, false_type());} - _LIBCPP_INLINE_VISIBILITY - void __destruct_at_end(const_pointer __new_last, false_type) _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY - void __destruct_at_end(const_pointer __new_last, true_type) _NOEXCEPT; + void __destruct_at_end(pointer __new_last) _NOEXCEPT;    _LIBCPP_INLINE_VISIBILITY  void __copy_assign_alloc(const __vector_base& __c) @@ -437,43 +432,35 @@  template <class _Tp, class _Allocator>  _LIBCPP_INLINE_VISIBILITY inline  void -__vector_base<_Tp, _Allocator>::__destruct_at_end(const_pointer __new_last, false_type) _NOEXCEPT +__vector_base<_Tp, _Allocator>::__destruct_at_end(pointer __new_last) _NOEXCEPT  {  while (__new_last != __end_) - __alloc_traits::destroy(__alloc(), const_cast<pointer>(--__end_)); -} - -template <class _Tp, class _Allocator> -_LIBCPP_INLINE_VISIBILITY inline -void -__vector_base<_Tp, _Allocator>::__destruct_at_end(const_pointer __new_last, true_type) _NOEXCEPT -{ - __end_ = const_cast<pointer>(__new_last); + __alloc_traits::destroy(__alloc(), _VSTD::__to_raw_pointer(--__end_));  }    template <class _Tp, class _Allocator>  _LIBCPP_INLINE_VISIBILITY inline  __vector_base<_Tp, _Allocator>::__vector_base()  _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) - : __begin_(0), - __end_(0), - __end_cap_(0) + : __begin_(nullptr), + __end_(nullptr), + __end_cap_(nullptr)  {  }    template <class _Tp, class _Allocator>  _LIBCPP_INLINE_VISIBILITY inline  __vector_base<_Tp, _Allocator>::__vector_base(const allocator_type& __a) - : __begin_(0), - __end_(0), - __end_cap_(0, __a) + : __begin_(nullptr), + __end_(nullptr), + __end_cap_(nullptr, __a)  {  }    template <class _Tp, class _Allocator>  __vector_base<_Tp, _Allocator>::~__vector_base()  { - if (__begin_ != 0) + if (__begin_ != nullptr)  {  clear();  __alloc_traits::deallocate(__alloc(), __begin_, capacity()); @@ -797,7 +784,7 @@  _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value);  void __move_assign(vector& __c, false_type);  _LIBCPP_INLINE_VISIBILITY - void __destruct_at_end(const_pointer __new_last) _NOEXCEPT + void __destruct_at_end(pointer __new_last) _NOEXCEPT  {  #if _LIBCPP_DEBUG_LEVEL >= 2  __c_node* __c = __get_db()->__find_c_and_lock(this); @@ -878,11 +865,11 @@  void  vector<_Tp, _Allocator>::deallocate() _NOEXCEPT  { - if (this->__begin_ != 0) + if (this->__begin_ != nullptr)  {  clear();  __alloc_traits::deallocate(this->__alloc(), this->__begin_, capacity()); - this->__begin_ = this->__end_ = this->__end_cap() = 0; + this->__begin_ = this->__end_ = this->__end_cap() = nullptr;  }  }   @@ -1171,7 +1158,7 @@  this->__begin_ = __x.__begin_;  this->__end_ = __x.__end_;  this->__end_cap() = __x.__end_cap(); - __x.__begin_ = __x.__end_ = __x.__end_cap() = 0; + __x.__begin_ = __x.__end_ = __x.__end_cap() = nullptr;  }    template <class _Tp, class _Allocator> @@ -1597,7 +1584,8 @@  #endif  _LIBCPP_ASSERT(__position != end(),  "vector::erase(iterator) called with a non-dereferenceable iterator"); - pointer __p = const_cast<pointer>(&*__position); + difference_type __ps = __position - cbegin(); + pointer __p = this->__begin_ + __ps;  iterator __r = __make_iter(__p);  this->__destruct_at_end(_VSTD::move(__p + 1, this->__end_, __p));  return __r; @@ -1943,9 +1931,9 @@  bool  vector<_Tp, _Allocator>::__invariants() const  { - if (this->__begin_ == 0) + if (this->__begin_ == nullptr)  { - if (this->__end_ != 0 || this->__end_cap() != 0) + if (this->__end_ != nullptr || this->__end_cap() != nullptr)  return false;  }  else @@ -2307,7 +2295,7 @@  {return const_iterator(__begin_ + __pos / __bits_per_word, static_cast<unsigned>(__pos % __bits_per_word));}  _LIBCPP_INLINE_VISIBILITY  iterator __const_iterator_cast(const_iterator __p) _NOEXCEPT - {return iterator(const_cast<__storage_pointer>(__p.__seg_), __p.__ctz_);} + {return begin() + (__p - cbegin());}  #endif // _LIBCPP_DEBUG    _LIBCPP_INLINE_VISIBILITY @@ -2414,11 +2402,11 @@  void  vector<bool, _Allocator>::deallocate() _NOEXCEPT  { - if (this->__begin_ != 0) + if (this->__begin_ != nullptr)  {  __storage_traits::deallocate(this->__alloc(), this->__begin_, __cap());  __invalidate_all_iterators(); - this->__begin_ = 0; + this->__begin_ = nullptr;  this->__size_ = this->__cap() = 0;  }  } @@ -2481,7 +2469,7 @@  _LIBCPP_INLINE_VISIBILITY inline  vector<bool, _Allocator>::vector()  _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) - : __begin_(0), + : __begin_(nullptr),  __size_(0),  __cap_alloc_(0)  { @@ -2490,7 +2478,7 @@  template <class _Allocator>  _LIBCPP_INLINE_VISIBILITY inline  vector<bool, _Allocator>::vector(const allocator_type& __a) - : __begin_(0), + : __begin_(nullptr),  __size_(0),  __cap_alloc_(0, static_cast<__storage_allocator>(__a))  { @@ -2498,7 +2486,7 @@    template <class _Allocator>  vector<bool, _Allocator>::vector(size_type __n) - : __begin_(0), + : __begin_(nullptr),  __size_(0),  __cap_alloc_(0)  { @@ -2511,7 +2499,7 @@    template <class _Allocator>  vector<bool, _Allocator>::vector(size_type __n, const value_type& __x) - : __begin_(0), + : __begin_(nullptr),  __size_(0),  __cap_alloc_(0)  { @@ -2524,7 +2512,7 @@    template <class _Allocator>  vector<bool, _Allocator>::vector(size_type __n, const value_type& __x, const allocator_type& __a) - : __begin_(0), + : __begin_(nullptr),  __size_(0),  __cap_alloc_(0, static_cast<__storage_allocator>(__a))  { @@ -2540,7 +2528,7 @@  vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last,  typename enable_if<__is_input_iterator <_InputIterator>::value &&  !__is_forward_iterator<_InputIterator>::value>::type*) - : __begin_(0), + : __begin_(nullptr),  __size_(0),  __cap_alloc_(0)  { @@ -2554,7 +2542,7 @@  }  catch (...)  { - if (__begin_ != 0) + if (__begin_ != nullptr)  __storage_traits::deallocate(__alloc(), __begin_, __cap());  __invalidate_all_iterators();  throw; @@ -2567,7 +2555,7 @@  vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a,  typename enable_if<__is_input_iterator <_InputIterator>::value &&  !__is_forward_iterator<_InputIterator>::value>::type*) - : __begin_(0), + : __begin_(nullptr),  __size_(0),  __cap_alloc_(0, static_cast<__storage_allocator>(__a))  { @@ -2581,7 +2569,7 @@  }  catch (...)  { - if (__begin_ != 0) + if (__begin_ != nullptr)  __storage_traits::deallocate(__alloc(), __begin_, __cap());  __invalidate_all_iterators();  throw; @@ -2593,7 +2581,7 @@  template <class _ForwardIterator>  vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last,  typename enable_if<__is_forward_iterator<_ForwardIterator>::value>::type*) - : __begin_(0), + : __begin_(nullptr),  __size_(0),  __cap_alloc_(0)  { @@ -2609,7 +2597,7 @@  template <class _ForwardIterator>  vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a,  typename enable_if<__is_forward_iterator<_ForwardIterator>::value>::type*) - : __begin_(0), + : __begin_(nullptr),  __size_(0),  __cap_alloc_(0, static_cast<__storage_allocator>(__a))  { @@ -2625,7 +2613,7 @@    template <class _Allocator>  vector<bool, _Allocator>::vector(initializer_list<value_type> __il) - : __begin_(0), + : __begin_(nullptr),  __size_(0),  __cap_alloc_(0)  { @@ -2639,7 +2627,7 @@    template <class _Allocator>  vector<bool, _Allocator>::vector(initializer_list<value_type> __il, const allocator_type& __a) - : __begin_(0), + : __begin_(nullptr),  __size_(0),  __cap_alloc_(0, static_cast<__storage_allocator>(__a))  { @@ -2656,7 +2644,7 @@  template <class _Allocator>  vector<bool, _Allocator>::~vector()  { - if (__begin_ != 0) + if (__begin_ != nullptr)  __storage_traits::deallocate(__alloc(), __begin_, __cap());  #ifdef _LIBCPP_DEBUG  __invalidate_all_iterators(); @@ -2665,7 +2653,7 @@    template <class _Allocator>  vector<bool, _Allocator>::vector(const vector& __v) - : __begin_(0), + : __begin_(nullptr),  __size_(0),  __cap_alloc_(0, __storage_traits::select_on_container_copy_construction(__v.__alloc()))  { @@ -2678,7 +2666,7 @@    template <class _Allocator>  vector<bool, _Allocator>::vector(const vector& __v, const allocator_type& __a) - : __begin_(0), + : __begin_(nullptr),  __size_(0),  __cap_alloc_(0, __a)  { @@ -2720,14 +2708,14 @@  __size_(__v.__size_),  __cap_alloc_(__v.__cap_alloc_)  { - __v.__begin_ = 0; + __v.__begin_ = nullptr;  __v.__size_ = 0;  __v.__cap() = 0;  }    template <class _Allocator>  vector<bool, _Allocator>::vector(vector&& __v, const allocator_type& __a) - : __begin_(0), + : __begin_(nullptr),  __size_(0),  __cap_alloc_(0, __a)  { @@ -3123,7 +3111,7 @@  bool  vector<bool, _Allocator>::__invariants() const  { - if (this->__begin_ == 0) + if (this->__begin_ == nullptr)  {  if (this->__size_ != 0 || this->__cap() != 0)  return false;